#include <tsin/util/EventMediator.hpp>
#include <tsin/util/EventListener.hpp>

#include <tsin/util/ArraySet.hpp>
#include <map>

using namespace tsin;

typedef ArraySet<EventListener *> ChannelList;
typedef std::map<int, ChannelList * > ChannelMap;

ChannelMap channels;

EventMediator *EventMediator::mediator = 0;

EventMediator::EventMediator()
        : eventRequested (0)
{
}

EventMediator::~EventMediator()
{
        clear();
}

EventMediator *EventMediator::get()
{
        if (mediator == 0)
                mediator = new EventMediator;
        return mediator;
}

void EventMediator::clear()
{
        for (ChannelMap::iterator it = channels.begin();
             it != channels.end();
             it ++) {
                delete it->second;
        }
}

int EventMediator::requestEventRange(int size)
{
        int eventBase = eventRequested;
        eventRequested += size;
        return eventBase;
}

void EventMediator::registerListener(EventListener *listener, int eventNo)
{
        ChannelList *list = channels[eventNo];
        if (list == 0) {
                list = new ChannelList(10);
                channels[eventNo] = list;
        }

        list->insert(listener);
}

void EventMediator::broadcastEvent(EventSource *source, int eventNo)
{
        ChannelList *list = channels[eventNo];
        if (list == 0)
                return;

        for (list->toBegin(); !list->atEnd(); list->next())
                list->get()->handle(source, eventNo);
}
